package com.wsd.jing.handler;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import com.wsd.jing.enums.CodeEnum;
import com.wsd.jing.exception.BusinessException;
import com.wsd.jing.request.CommonResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.List;
import java.util.Set;

/**
 * All rights Reserved, Designed By www.tom.com
 *
 * @author tom
 * @version 1.0.0
 * @projectName: jing
 * @packageName: com.wsd.jing.handler
 * @className: GlobalExceptionHandler
 * @description 全局异常处理类
 * @createDate 2022/11/14 17:17
 * @copyright 2022/11/14 17:17 www.tom.com Inc. All rights reserved.
 */
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

    /**
     * @param e:
     * @return CommonResponse
     * @author tom
     * @description 处理全局异常
     * @createDate 2022/11/14 17:39
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public CommonResponse handleException(Exception e) {
        e.printStackTrace();
        return CommonResponse.failed(CodeEnum.FAILED);
    }

    /**
     * @param e:
     * @return CommonResponse
     * @author tom
     * @description 处理业务异常
     * @createDate 2022/11/14 17:38
     */
    @ExceptionHandler(BusinessException.class)
    @ResponseBody
    public CommonResponse handleBusinessException(BusinessException e) {
        return CommonResponse.failed(e.getCode(), e.getMessage());
    }

    /**
     * @param e:
     * @return CommonResponse
     * @author tom
     * @description 处理登录相关异常
     * @createDate 2024/8/5 18:09
     */
    @ExceptionHandler(NotLoginException.class)
    @ResponseBody
    public CommonResponse handlerNotLoginException(NotLoginException e) {
        return CommonResponse.failed(CodeEnum.UNAUTHORIZED);
    }

    /**
     * @param e:
     * @return CommonResponse
     * @author tom
     * @description 处理无权限异常
     * @createDate 2022/11/14 17:38
     */
    @ExceptionHandler(NotPermissionException.class)
    @ResponseBody
    public CommonResponse handlePermissionException(NotPermissionException e) {
        return CommonResponse.failed(CodeEnum.FORBIDDEN);
    }

    /**
     * @param e:
     * @return CommonResponse
     * @author tom
     * @description 处理controll层参数类型转换异常
     * @createDate 2022/11/28 19:16
     */
    @ExceptionHandler(value = MethodArgumentTypeMismatchException.class)
    @ResponseBody
    public CommonResponse handleConstraintViolationException(MethodArgumentTypeMismatchException e) {
        return CommonResponse.failed(CodeEnum.VALIDATE_FAILED);
    }

    /**
     * @param e:
     * @return CommonResponse
     * @author tom
     * @description 处理controll层validator参数校验异常
     * @createDate 2022/11/28 19:16
     */
    @ExceptionHandler(value = ConstraintViolationException.class)
    @ResponseBody
    public CommonResponse handleConstraintViolationException(ConstraintViolationException e) {
        String message = "";
        Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
        for (ConstraintViolation<?> violation : violations) {
            message = violation.getMessage();
            break;
        }
        return CommonResponse.failed(CodeEnum.VALIDATE_FAILED, message);
    }

    /**
     * @param e:
     * @return CommonResponse
     * @author tom
     * @description 处理entity层validator参数校验异常
     * @createDate 2022/11/28 19:14
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public CommonResponse handlerMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        List<FieldError> fieldErrorList = e.getBindingResult().getFieldErrors();
        String message = fieldErrorList.get(0).getDefaultMessage();
        return CommonResponse.failed(CodeEnum.VALIDATE_FAILED, message);
    }
}
